package com.tianshi.agriculture.ui.home;

import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.tianshi.agriculture.R;
import com.tianshi.agriculture.databinding.WriteDataLayoutBinding;
import com.tianshi.agriculture.utils.Ble.hansion.h_ble.BleController;
import com.tianshi.agriculture.utils.Ble.hansion.h_ble.callback.OnReceiverCallback;
import com.tianshi.agriculture.utils.Ble.hansion.h_ble.callback.OnWriteCallback;
import com.tianshi.agriculture.utils.ModbusUtils.ByteUtil;
import com.tianshi.agriculture.utils.ModbusUtils.ModbusError;
import com.tianshi.agriculture.utils.ModbusUtils.ModbusRTUHelper;
import com.tianshi.agriculture.utils.ToolsUtil;

import java.util.Arrays;

import kotlin.ULong;

public class WriteDataFragment extends Fragment {

    private WriteDataLayoutBinding binding;
    private boolean dataReading = false; //用于避免在此阶段产生的 checkedChange会发送写入命令
    private static WriteDataFragment instance = null;
    public static final String REQUESTKEY_SENDANDRECIVEACTIVITY = "WriteDataFragment";
    private int retryTimes = 3;

    @Override
    public void onStart() {
        super.onStart();
        enterFragment();

        //进页面先读取一次全部参数
        binding.readDataInWritePage.performClick();
    }

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        instance = this;
        WriteDataModel writeDataModel =
                new ViewModelProvider(this).get(WriteDataModel.class);

        binding = WriteDataLayoutBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        View.OnClickListener readAllDataListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    byte[] bytes1 = ModbusRTUHelper.readHoldingRegisters(1, 0, 100);

                    System.out.println("发送=>>>>" + BleController.getInstance().bytesToHexString(bytes1));
                    BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                        @Override
                        public void onSuccess() {
						    Toast.makeText(getActivity(), "发送成功！", Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onFailed(int state) {
                            Toast.makeText(getActivity(), "发送失败！", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (ModbusError e) {
                    throw new RuntimeException(e);
                }
            }
        };

        binding.readDataInWritePage.setOnClickListener(readAllDataListener);
        binding.readDataInWritePage2.setOnClickListener(readAllDataListener);

        CompoundButton.OnCheckedChangeListener ioControlListener = new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(dataReading) return;

                //处理IO输出控制
                short ioControl = 0;
                if(binding.isCloseValue.isChecked()) {
                    ioControl |= (short)(1<<0);
                }
                if(binding.isOpenValue.isChecked())
                {
                    ioControl |= (1<<1);
                }
                if(binding.angleGetZero.isChecked()){
                    ioControl |= (1<<4);
                }
                if(binding.angleGetfull.isChecked()){
                    ioControl |= (1<<5);
                }

                if(binding.angleGetZero2s.isChecked()){
                    ioControl |= (1<<6);
                }
                if(binding.angleGetfull2s.isChecked()){
                    ioControl |= (1<<7);
                }
                if(binding.saveParamAfterAngleGetValue.isChecked()){
                    ioControl |= (1<<8);
                }

                int[] writeInt16 = new int[1];
                writeInt16[0] = ioControl;
                try {
                    byte[] bytes1 = ModbusRTUHelper.writeHoldingRegisters(1, 0,1, writeInt16);


                    System.out.println("发送:>>>" + BleController.getInstance().bytesToHexString(bytes1));
                    BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                        @Override
                        public void onSuccess() {
//                            Toast.makeText(getActivity(), "IO控制发送成功！", Toast.LENGTH_SHORT).show();

                            //binding.readDataInWritePage.performClick();
                        }

                        @Override
                        public void onFailed(int state) {
                            Toast.makeText(getActivity(), "IO控制发送失败！", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (ModbusError e) {
                    throw new RuntimeException(e);
                }

            }
        };

        binding.isCloseValue.setOnCheckedChangeListener(ioControlListener);
        binding.isOpenValue.setOnCheckedChangeListener(ioControlListener);
        binding.angleGetZero.setOnCheckedChangeListener(ioControlListener);
        binding.angleGetfull.setOnCheckedChangeListener(ioControlListener);
        binding.angleGetZero2s.setOnCheckedChangeListener(ioControlListener);
        binding.angleGetfull2s.setOnCheckedChangeListener(ioControlListener);
        binding.saveParamAfterAngleGetValue.setOnCheckedChangeListener(ioControlListener);

        binding.changeValueKD.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int[] writeInt16 = new int[1];

                if(!ToolsUtil.IsValidFloat(binding.valueWriteValueKD.getText().toString(),0,100))
                {
                    Toast.makeText(getActivity(),"阀开度控制（不是整数，或不在0-100之间)",Toast.LENGTH_SHORT);
                    return;
                }

                writeInt16[0] = (int) Float.parseFloat(binding.valueWriteValueKD.getText().toString());
                byte[] bytes1 = null;
                try {
                    bytes1 = ModbusRTUHelper.writeHoldingRegisters(1, 1,1, writeInt16);
                } catch (ModbusError e) {
                    throw new RuntimeException(e);
                }

                System.out.println("发送:>>>" + BleController.getInstance().bytesToHexString(bytes1));
                BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                    @Override
                    public void onSuccess() {
//                        Toast.makeText(getActivity(), "开度控制修改成功！", Toast.LENGTH_SHORT).show();
                        //binding.readDataInWritePage.performClick();
                    }

                    @Override
                    public void onFailed(int state) {
                        Toast.makeText(getActivity(), "开度控制修改失败！", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

        binding.changeValueWD.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(!ToolsUtil.IsValidFloat(binding.valueWriteValueWD.getText().toString(),0,100))
                {
                    Toast.makeText(getActivity(),"阀温度控制（不是整数，或不在0-100之间)",Toast.LENGTH_SHORT);
                    return;
                }

                Integer valueWDNew = (int)Float.parseFloat(binding.valueWriteValueWD.getText().toString());

                int[] writeInt16 = new int[1];
                writeInt16[0] = valueWDNew * 100;
                byte[] bytes1 = null;
                try {
                    bytes1 = ModbusRTUHelper.writeHoldingRegisters(1, 2,1, writeInt16);
                } catch (ModbusError e) {
                    throw new RuntimeException(e);
                }

                System.out.println("发送:>>>" + BleController.getInstance().bytesToHexString(bytes1));
                BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                    @Override
                    public void onSuccess() {
//                        Toast.makeText(getActivity(), "温度控制修改成功！", Toast.LENGTH_SHORT).show();
                        //binding.readDataInWritePage.performClick();
                    }

                    @Override
                    public void onFailed(int state) {
                        Toast.makeText(getActivity(), "温度控制修改失败！", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

        binding.changeValueEquiNo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                long valueWDNew = Long.parseLong(binding.valueWriteEquiNo.getText().toString());

                byte[] dataBytes = ByteUtil.int32ToBytes((int)valueWDNew);
                int[] writeInt32 = new int[2];
                writeInt32[0] = ByteUtil.bytesToUint16(dataBytes[0],dataBytes[1]);
                writeInt32[1] = ByteUtil.bytesToUint16(dataBytes[2],dataBytes[3]);;

                byte[] bytes1 = null;
                try {
                    bytes1 = ModbusRTUHelper.writeHoldingRegisters(1, 93,2, writeInt32);
                } catch (ModbusError e) {
                    throw new RuntimeException(e);
                }

                System.out.println("发送:>>>" + BleController.getInstance().bytesToHexString(bytes1));
                BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                    @Override
                    public void onSuccess() {
//                        Toast.makeText(getActivity(), "温度控制修改成功！", Toast.LENGTH_SHORT).show();
                        //binding.readDataInWritePage.performClick();
                    }

                    @Override
                    public void onFailed(int state) {
                        Toast.makeText(getActivity(), "Equi序列号修改失败！", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

        binding.writeSettingButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //处理Modbus模式
                int[] settingData = new int[6];

                short modbusMode = 0 ;
                if(binding.valueWriteModbusMode0.isChecked()) {
                    modbusMode = 0;
                } else if(binding.valueWriteModbusMode1.isChecked()) {
                    modbusMode = 1;
                }
                else if(binding.valueWriteModbusMode2.isChecked()) {
                    modbusMode = 2;
                }

                Integer deviceId = Integer.valueOf(binding.valueWriteDeviceId.getText().toString());

                if(!ToolsUtil.IsValidShort(binding.valueWriteDeviceId.getText().toString(),1,255)) {
                    Toast.makeText(getActivity(),"设备ID值无效（不是数字，或不在1-255之间)",Toast.LENGTH_SHORT);
                    return;
                }

                //设置波特率
                short baudrate = 0 ;
                if(binding.valueWriteBaudrate0.isChecked()) {
                    baudrate = 0;
                } else if(binding.valueWriteBaudrate1.isChecked()) {
                    baudrate = 1;
                } else if(binding.valueWriteBaudrate2.isChecked()) {
                    baudrate = 2;
                } else if(binding.valueWriteBaudrate3.isChecked()) {
                    baudrate = 3;
                } else if(binding.valueWriteBaudrate4.isChecked()) {
                    baudrate = 4;
                } else if(binding.valueWriteBaudrate5.isChecked()) {
                    baudrate = 5;
                } else if(binding.valueWriteBaudrate6.isChecked()) {
                    baudrate = 6;
                } else if(binding.valueWriteBaudrate7.isChecked()) {
                    baudrate = 7;
                }

                short dataBits = 0;
                if(binding.valueWriteDataBits0.isChecked()) {
                    dataBits = 0;
                } else if(binding.valueWriteDataBits1.isChecked()) {
                    dataBits = 1;
                }

                short verifyBits = 0;
                if(binding.valueWriteVerifyBits0.isChecked()) {
                    verifyBits = 0;
                } else if(binding.valueWriteVerifyBits1.isChecked()) {
                    verifyBits = 1;
                } else if(binding.valueWriteVerifyBits2.isChecked()) {
                    verifyBits = 2;
                }

                short stopBits = 0 ;
                if(binding.valueWriteStopBits0.isChecked()) {
                    stopBits = 0;
                } else if(binding.valueWriteStopBits1.isChecked()) {
                    stopBits = 1;
                }

                settingData[0] = modbusMode;
                settingData[1] = deviceId;
                settingData[2] = baudrate;
                settingData[3] = dataBits;
                settingData[4] = verifyBits;
                settingData[5] = stopBits;

                byte[] bytes1 = null;
                try {
                    bytes1 = ModbusRTUHelper.writeHoldingRegisters(1, 7,6, settingData);
                } catch (ModbusError e) {
                    throw new RuntimeException(e);
                }

                System.out.println("发送:>>>" + BleController.getInstance().bytesToHexString(bytes1));
                BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                    @Override
                    public void onSuccess() {
//                        Toast.makeText(getActivity(), "通讯参数配置修改成功！", Toast.LENGTH_SHORT).show();

                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                        byte[] bytes1 = null;

                        int controlMode = 0;
                        if(binding.rbControlMode0.isChecked()) {
                            controlMode = 0;
                        } else if(binding.rbControlMode1.isChecked()) {
                            controlMode = 1;
                        } else if(binding.rbControlMode2.isChecked()) {
                            controlMode = 2;
                        }

                        //控制模式
                        int[] writeInt16 = new int[1];
                        writeInt16[0] = controlMode;
                        try {
                            bytes1 = ModbusRTUHelper.writeHoldingRegisters(1, 14,1, writeInt16);
                        } catch (ModbusError e) {
                            throw new RuntimeException(e);
                        }

//                      System.out.println("发送:>>>" + BleController.getInstance().bytesToHexString(bytes1));
                        BleController.getInstance().writeBuffer(bytes1, new OnWriteCallback() {
                            @Override
                            public void onSuccess() {
                            }

                            @Override
                            public void onFailed(int state) {
                                Toast.makeText(getActivity(), "控制模式修改失败！", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }

                    @Override
                    public void onFailed(int state) {
                        Toast.makeText(getActivity(), "通讯参数配置修改失败！", Toast.LENGTH_SHORT).show();
                    }
                });




                //binding.readDataInWritePage.performClick();
            }
        });

        return root;
    }


    public void exitFragment() {
        BleController.getInstance().unregistReciveListener(REQUESTKEY_SENDANDRECIVEACTIVITY);

    }

    public void enterFragment() {
        BleController.getInstance().unregistReciveListener(REQUESTKEY_SENDANDRECIVEACTIVITY);
        // TODO 接收数据的监听
        BleController.getInstance().registReciveListener(REQUESTKEY_SENDANDRECIVEACTIVITY, new OnReceiverCallback() {
            @Override
            public void onRecive(byte[] value) {

                try {
                    if (binding == null) {
                        return;
                    }

                    System.out.println("接收：>>" + BleController.getInstance().bytesToHexString(value));
                    if (value.length != 205) {
                        Toast.makeText(getActivity(), "接收到数据，但长度不是205", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    if (value[0] != 0x01 && value[1] != 0x03) {
                        Toast.makeText(getActivity(), "接收到数据，但数据开头字节不正确", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    dataReading = true;
                    value = Arrays.copyOfRange(value, 3, value.length);
                    // 这里为了演示方便，把 byte数组转字符串显示
                    short ioControl = ByteUtil.bytesToInt16(value[0 * 2], value[0 * 2 + 1]);  //IO输出控制
                    int fkdkz = ByteUtil.bytesToUint16(value[1 * 2], value[1 * 2 + 1]);  //阀开度控制
                    int fwdkz = ByteUtil.bytesToUint16(value[2 * 2], value[2 * 2 + 1]);  //阀温度控制
                    short reserve1 = ByteUtil.bytesToInt16(value[3 * 2], value[3 * 2 + 1]); //备用
                    short reserve2 = ByteUtil.bytesToInt16(value[4 * 2], value[4 * 2 + 1]); //备用
                    short reserve3 = ByteUtil.bytesToInt16(value[5 * 2], value[5 * 2 + 1]); //备用
                    short reserve4 = ByteUtil.bytesToInt16(value[6 * 2], value[6 * 2 + 1]); //备用
                    short modbusMode = ByteUtil.bytesToInt16(value[7 * 2], value[7 * 2 + 1]); //进水温度
                    short deviceId = ByteUtil.bytesToInt16(value[8 * 2], value[8 * 2 + 1]); //回水温度
                    short baudrate = ByteUtil.bytesToInt16(value[9 * 2], value[9 * 2 + 1]); //保留
                    short dataBits = ByteUtil.bytesToInt16(value[10 * 2], value[10 * 2 + 1]); //保留
                    short verifyBits = ByteUtil.bytesToInt16(value[11 * 2], value[11 * 2 + 1]); //保留
                    short stopBits = ByteUtil.bytesToInt16(value[12 * 2], value[12 * 2 + 1]); //保留
                    int valluePWM = ByteUtil.bytesToUint16(value[13 * 2], value[13 * 2 + 1]); //错误号
                    short controlMode = ByteUtil.bytesToInt16(value[14 * 2], value[14 * 2 + 1]); //报警状态
                    short reserve5 = ByteUtil.bytesToInt16(value[15 * 2], value[15 * 2 + 1]); //保留
                    short reserve6 = ByteUtil.bytesToInt16(value[16 * 2], value[16 * 2 + 1]); //保留
                    int functionValidConfig = ByteUtil.bytesToUint16(value[17 * 2], value[17 * 2 + 1]); //回水温度
                    short reserve7 = ByteUtil.bytesToInt16(value[18 * 2], value[18 * 2 + 1]); //回水温度
                    short reserve8 = ByteUtil.bytesToInt16(value[19 * 2], value[19 * 2 + 1]); //回水温度
                    long equiNo = ByteUtil.bytesToUint32(value[93 * 2], value[93 * 2 + 1], value[93 * 2 + 2], value[93 * 2 + 3]); //EquiNO

                    boolean isCloseValueValue = isBit1(ioControl, 0);
                    boolean isOpenValueValue = isBit1(ioControl, 1);
                    boolean angleGetZeroValue = isBit1(ioControl, 4);
                    boolean angleGetfullValue = isBit1(ioControl, 5);
                    boolean angleGetZero2sValue = isBit1(ioControl, 6);
                    boolean angleGetfull2sValue = isBit1(ioControl, 7);
                    boolean saveParamAfterAngleGetValueValue = isBit1(ioControl, 8);

                    binding.isCloseValue.setChecked(isCloseValueValue);
                    binding.isOpenValue.setChecked(isOpenValueValue);
                    binding.angleGetZero.setChecked(angleGetZeroValue);
                    binding.angleGetfull.setChecked(angleGetfullValue);
                    binding.angleGetZero2s.setChecked(angleGetZero2sValue);
                    binding.angleGetfull2s.setChecked(angleGetfull2sValue);
                    binding.saveParamAfterAngleGetValue.setChecked(saveParamAfterAngleGetValueValue);


                    double fkdkzValue = fkdkz;
                    double fwdkzValue = fwdkz * 0.01;


                    binding.valueWriteValueKD.setText(fkdkzValue + "");
                    binding.valueWriteValueWD.setText(fwdkzValue + "");
                    switch (modbusMode) {
                        case 0:
                            binding.valueWriteModbusMode0.setChecked(true);
                            break;
                        case 1:
                            binding.valueWriteModbusMode1.setChecked(true);
                            break;
                        case 2:
                            binding.valueWriteModbusMode2.setChecked(true);
                            break;
                        default:
                            break;
                    }

                    binding.valueWriteDeviceId.setText(deviceId + "");
                    switch (baudrate) {
                        case 0:
                            binding.valueWriteBaudrate0.setChecked(true);
                            break;
                        case 1:
                            binding.valueWriteBaudrate1.setChecked(true);
                            break;
                        case 2:
                            binding.valueWriteBaudrate2.setChecked(true);
                            break;
                        case 3:
                            binding.valueWriteBaudrate3.setChecked(true);
                            break;
                        case 4:
                            binding.valueWriteBaudrate4.setChecked(true);
                            break;
                        case 5:
                            binding.valueWriteBaudrate5.setChecked(true);
                            break;
                        case 6:
                            binding.valueWriteBaudrate6.setChecked(true);
                            break;
                        case 7:
                            binding.valueWriteBaudrate7.setChecked(true);
                            break;
                    }

                    switch (dataBits) {
                        case 0:
                            binding.valueWriteDataBits0.setChecked(true);
                            break;
                        case 1:
                            binding.valueWriteDataBits1.setChecked(true);
                            break;
                        default:
                            break;
                    }

                    switch (verifyBits) {
                        case 0:
                            binding.valueWriteVerifyBits0.setChecked(true);
                            break;
                        case 1:
                            binding.valueWriteVerifyBits1.setChecked(true);
                            break;
                        case 2:
                            binding.valueWriteVerifyBits2.setChecked(true);
                            break;
                        default:
                            break;
                    }

                    switch (stopBits) {
                        case 0:
                            binding.valueWriteStopBits0.setChecked(true);
                            break;
                        case 1:
                            binding.valueWriteStopBits1.setChecked(true);
                            break;
                    }

                    switch (controlMode) {
                        case 0:
                            binding.rbControlMode0.setChecked(true);
                            break;
                        case 1:
                            binding.rbControlMode1.setChecked(true);
                            break;
                        case 2:
                            binding.rbControlMode2.setChecked(true);
                            break;
                    }

                    binding.valueWriteEquiNo.setText(equiNo + "");
                    dataReading = false;

                    Toast.makeText(getActivity(), "全部数据读取成功！", Toast.LENGTH_SHORT).show();
                }
                catch (Exception e) {
                    Toast.makeText(getActivity(), "数据读取成功，但是发生异常" + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public static WriteDataFragment getInstance() {
        return instance;
    }


    public boolean isBit1(short value,int positionBase0) {
        // 使用位掩码和按位与运算判断位值
        boolean bitValue = (value & (1 << positionBase0))!= 0;
        return bitValue;
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        exitFragment();
        binding = null;
    }


}